//+------------------------------------------------------------------+
//|                                            MA_Angle_Indicator.mq5 |
//|                                    Copyright 2024, Claude Code   |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, Claude Code"
#property link      ""
#property version   "1.00"
#property indicator_separate_window
#property indicator_buffers 3
#property indicator_plots   3

// 指标线设置
#property indicator_label1  "MA角度"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrDodgerBlue
#property indicator_style1  STYLE_SOLID
#property indicator_width1  2

#property indicator_label2  "上涨阈值"
#property indicator_type2   DRAW_LINE
#property indicator_color2  clrLime
#property indicator_style2  STYLE_DOT
#property indicator_width2  1

#property indicator_label3  "下跌阈值"
#property indicator_type3   DRAW_LINE
#property indicator_color3  clrRed
#property indicator_style3  STYLE_DOT
#property indicator_width3  1

//+------------------------------------------------------------------+
//| 输入参数                                                          |
//+------------------------------------------------------------------+
input group "均线参数"
input int    MAPeriod = 20;                    // 均线周期
input ENUM_MA_METHOD MAMethod = MODE_SMA;      // 均线类型
input ENUM_APPLIED_PRICE MAPrice = PRICE_CLOSE; // 均线价格

input group "角度计算参数"
input double MAAngleThreshold = 0.00001;      // 角度阈值（上涨/下跌判断）
input int    AngleCalculateBars = 5;          // 角度计算K线数量
input double Weight1 = 0.4;                   // 最新变化权重
input double Weight2 = 0.3;                   // 第2新变化权重  
input double Weight3 = 0.2;                   // 第3新变化权重
input double Weight4 = 0.1;                   // 第4新变化权重

input group "显示设置"
input bool   ShowThresholdLines = true;       // 显示阈值线
input bool   ShowInfoPanel = true;            // 显示信息面板
input color  PanelColor = clrWhite;           // 面板文字颜色
input int    PanelX = 10;                     // 面板X坐标
input int    PanelY = 30;                     // 面板Y坐标

//+------------------------------------------------------------------+
//| 全局变量                                                          |
//+------------------------------------------------------------------+
double AngleBuffer[];           // 角度线缓冲区
double UpperThresholdBuffer[];  // 上阈值线缓冲区
double LowerThresholdBuffer[];  // 下阈值线缓冲区

int    maHandle = INVALID_HANDLE; // 均线句柄
string indicatorShortName;        // 指标短名称

//+------------------------------------------------------------------+
//| 自定义指标初始化函数                                              |
//+------------------------------------------------------------------+
int OnInit()
{
    // 设置缓冲区
    SetIndexBuffer(0, AngleBuffer, INDICATOR_DATA);
    SetIndexBuffer(1, UpperThresholdBuffer, INDICATOR_DATA);
    SetIndexBuffer(2, LowerThresholdBuffer, INDICATOR_DATA);
    
    // 设置指标短名称
    indicatorShortName = StringFormat("MA角度线(%d,%s,%.5f)", 
                                     MAPeriod, 
                                     EnumToString(MAMethod), 
                                     MAAngleThreshold);
    IndicatorSetString(INDICATOR_SHORTNAME, indicatorShortName);
    
    // 设置指标精度
    IndicatorSetInteger(INDICATOR_DIGITS, 6);
    
    // 初始化均线指标
    maHandle = iMA(Symbol(), PERIOD_CURRENT, MAPeriod, 0, MAMethod, MAPrice);
    if(maHandle == INVALID_HANDLE)
    {
        Print("均线指标初始化失败");
        return(INIT_FAILED);
    }
    
    // 设置起始索引（需要足够的历史数据）
    PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, AngleCalculateBars);
    PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, 0);
    PlotIndexSetInteger(2, PLOT_DRAW_BEGIN, 0);
    
    Print("MA角度指标初始化成功");
    return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| 自定义指标释放函数                                                |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
    // 释放均线句柄
    if(maHandle != INVALID_HANDLE)
    {
        IndicatorRelease(maHandle);
    }
    
    // 删除所有对象
    ObjectsDeleteAll(0, "MA_Angle_Panel");
    
    Print("MA角度指标释放完成");
}

//+------------------------------------------------------------------+
//| 自定义指标迭代函数                                                |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
{
    // 检查数据是否足够
    if(rates_total < AngleCalculateBars)
        return(0);
    
    // 确定计算起始位置
    int start = prev_calculated > 0 ? prev_calculated - 1 : AngleCalculateBars - 1;
    if(start < AngleCalculateBars - 1)
        start = AngleCalculateBars - 1;
    
    // 获取MA数据
    double ma[];
    if(CopyBuffer(maHandle, 0, 0, rates_total, ma) <= 0)
        return(prev_calculated);
    
    // 计算角度线
    for(int i = start; i < rates_total; i++)
    {
        // 计算当前K线的MA角度
        double angle = CalculateMAngleAtBar(ma, i);
        AngleBuffer[i] = angle;
        
        // 设置阈值线
        if(ShowThresholdLines)
        {
            UpperThresholdBuffer[i] = MAAngleThreshold;
            LowerThresholdBuffer[i] = -MAAngleThreshold;
        }
        else
        {
            UpperThresholdBuffer[i] = EMPTY_VALUE;
            LowerThresholdBuffer[i] = EMPTY_VALUE;
        }
    }
    
    // 显示信息面板（仅最新K线）
    if(ShowInfoPanel && rates_total > 0)
    {
        UpdateInfoPanel(AngleBuffer[rates_total - 1]);
    }
    
    return(rates_total);
}

//+------------------------------------------------------------------+
//| 计算指定K线的MA角度                                               |
//+------------------------------------------------------------------+
double CalculateMAngleAtBar(const double &ma[], int bar)
{
    // 确保有足够的历史数据
    if(bar < AngleCalculateBars - 1)
        return(0.0);
    
    // 计算相邻MA值的变化量
    double angle1 = ma[bar] - ma[bar - 1];      // 最新变化
    double angle2 = ma[bar - 1] - ma[bar - 2];  // 第2新变化
    double angle3 = ma[bar - 2] - ma[bar - 3];  // 第3新变化
    double angle4 = ma[bar - 3] - ma[bar - 4];  // 第4新变化
    
    // 加权平均计算角度
    double weightedAngle = angle1 * Weight1 + 
                          angle2 * Weight2 + 
                          angle3 * Weight3 + 
                          angle4 * Weight4;
    
    return(weightedAngle);
}

//+------------------------------------------------------------------+
//| 更新信息面板                                                      |
//+------------------------------------------------------------------+
void UpdateInfoPanel(double currentAngle)
{
    if(!ShowInfoPanel)
        return;
    
    // 删除旧的面板对象
    ObjectsDeleteAll(0, "MA_Angle_Panel");
    
    // 创建面板背景
    string bgName = "MA_Angle_Panel_BG";
    if(ObjectCreate(0, bgName, OBJ_RECTANGLE_LABEL, 0, 0, 0))
    {
        ObjectSetInteger(0, bgName, OBJPROP_XDISTANCE, PanelX);
        ObjectSetInteger(0, bgName, OBJPROP_YDISTANCE, PanelY);
        ObjectSetInteger(0, bgName, OBJPROP_XSIZE, 250);
        ObjectSetInteger(0, bgName, OBJPROP_YSIZE, 120);
        ObjectSetInteger(0, bgName, OBJPROP_BGCOLOR, clrBlack);
        ObjectSetInteger(0, bgName, OBJPROP_BORDER_TYPE, BORDER_FLAT);
        ObjectSetInteger(0, bgName, OBJPROP_COLOR, clrGray);
        ObjectSetInteger(0, bgName, OBJPROP_CORNER, CORNER_LEFT_UPPER);
    }
    
    // 显示标题
    CreatePanelText("MA_Angle_Panel_Title", "MA角度线指标", PanelX + 10, PanelY + 10, clrYellow, 10);
    
    // 显示当前角度值
    string angleText = StringFormat("当前角度: %.6f", currentAngle);
    color angleColor = (currentAngle > MAAngleThreshold) ? clrLime : 
                      (currentAngle < -MAAngleThreshold) ? clrRed : clrWhite;
    CreatePanelText("MA_Angle_Panel_Value", angleText, PanelX + 10, PanelY + 30, angleColor, 9);
    
    // 显示趋势方向
    string trendText = "趋势: ";
    if(currentAngle > MAAngleThreshold)
        trendText += "上涨 ↗";
    else if(currentAngle < -MAAngleThreshold)
        trendText += "下跌 ↘";
    else
        trendText += "盘整 →";
    
    CreatePanelText("MA_Angle_Panel_Trend", trendText, PanelX + 10, PanelY + 50, angleColor, 9);
    
    // 显示阈值
    string thresholdText = StringFormat("阈值: ±%.6f", MAAngleThreshold);
    CreatePanelText("MA_Angle_Panel_Threshold", thresholdText, PanelX + 10, PanelY + 70, clrGray, 8);
    
    // 显示MA参数
    string maText = StringFormat("MA(%d,%s)", MAPeriod, EnumToString(MAMethod));
    CreatePanelText("MA_Angle_Panel_MA", maText, PanelX + 10, PanelY + 90, clrGray, 8);
}

//+------------------------------------------------------------------+
//| 创建面板文字                                                      |
//+------------------------------------------------------------------+
void CreatePanelText(string name, string text, int x, int y, color textColor, int fontSize)
{
    if(ObjectCreate(0, name, OBJ_LABEL, 0, 0, 0))
    {
        ObjectSetString(0, name, OBJPROP_TEXT, text);
        ObjectSetInteger(0, name, OBJPROP_XDISTANCE, x);
        ObjectSetInteger(0, name, OBJPROP_YDISTANCE, y);
        ObjectSetInteger(0, name, OBJPROP_COLOR, textColor);
        ObjectSetInteger(0, name, OBJPROP_FONTSIZE, fontSize);
        ObjectSetString(0, name, OBJPROP_FONT, "Arial");
        ObjectSetInteger(0, name, OBJPROP_CORNER, CORNER_LEFT_UPPER);
    }
}

//+------------------------------------------------------------------+
//| ChartEvent函数                                                   |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
{
    // 处理图表事件（如需要的话）
}